package com.sp.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.sp.mapper.MenuMapper;
import com.sp.model.entity.Menu;
import com.sp.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.sp.constant.RedisConstant.*;

/**
 * @author tong
 * @date 2024/4/15 10:08
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<Menu> getMenusByRoleIds(List<Integer> roleIds) {
        HashSet<Menu> menusSet = new HashSet<>();

        for (Integer roleId : roleIds) {
            String json = stringRedisTemplate.opsForValue().get(EMPLOYEE_MENU_ROLE + roleId);
            if (StrUtil.isNotBlank(json)) {
                menusSet.addAll(JSONObject.parseArray(json, Menu.class));
                continue;
            }

            List<Menu> menus = menuMapper.selectByRoleId(roleId);
            stringRedisTemplate.opsForValue().set(EMPLOYEE_MENU_ROLE + roleId, JSONObject.toJSONString(menus),
                    EMPLOYEE_MENU_ROLE_TTL, TimeUnit.MINUTES);
            menusSet.addAll(menus);
        }

        ArrayList<Menu> menus = new ArrayList<>(menusSet);
        menus.sort(new Comparator<Menu>() {
            @Override
            public int compare(Menu menu1, Menu menu2) {
                return menu1.getId() - menu2.getId();
            }
        });
        return menus;
    }

    @Override
    public List<Menu> selectAll() {
        return this.selectAllFromRedis();
    }

    /**
     * 从缓存获取所有界面菜单
     *
     * @return
     */
    private List<Menu> selectAllFromRedis() {
        String json = stringRedisTemplate.opsForValue().get(EMPLOYEE_MENUS);
        if (StrUtil.isNotBlank(json)) {
            return JSONObject.parseArray(json, Menu.class);
        }

        // 缓存不存在
        List<Menu> menus = menuMapper.selectAll();
        stringRedisTemplate.opsForValue().set(EMPLOYEE_MENUS, JSONObject.toJSONString(menus),
                EMPLOYEE_MENUS_TTL, TimeUnit.MINUTES);
        return menus;
    }

    @Override
    public Map<Integer, Menu> selectAllMap() {
        return this.selectAllMapFromRedis();
    }

    /**
     * 从缓存中获取所有具体权限 map
     *
     * @return
     */
    private Map<Integer, Menu> selectAllMapFromRedis() {
        List<Menu> menus = this.selectAllFromRedis();
        HashMap<Integer, Menu> hashMap = new HashMap<>();
        for (Menu menu : menus) {
            hashMap.put(menu.getId(), menu);
        }
        return hashMap;
    }

}
